<script setup lang="ts">
import { isNumber, merge } from 'lodash-es';
import { useDraggable } from '@pureadmin/utils';

import type { ModalMethods, ModalProps } from '@/components/modal/src/types';
import { basicProps } from '@/components/modal/src/props';

const props = defineProps(basicProps);

const emits = defineEmits<{
  (e: 'close'): void;
  (e: 'confirm'): void;
  (e: 'register', modalMethods: ModalMethods): void;
}>();

/**
 * 弹窗宽度
 */
const modalWidth = computed(() => {
  if (isNumber(props.width)) {
    return `${props.width}px`;
  }

  return props.width ?? '50vw';
});

/**
 * 属性绑定
 */
const attrs = useAttrs();
const propsRef = ref<Partial<ModalProps> | null>(null);
async function setProps(modalProps: Partial<ModalProps>): Promise<void> {
  propsRef.value = merge(unref(propsRef) || ({} as any), modalProps);
}
const getBindValue = computed(() => {
  return {
    ...attrs,
    ...unref(props),
    ...unref(propsRef),
    style: {
      width: modalWidth.value,
    },
  };
});

const { init } = useDraggable(
  '.n-dialog',
  '.n-dialog__title',
);

/**
 * 弹窗开关
 */
const isModal = ref(false);
function openModal() {
  isModal.value = true;
  init();
}
function closeModal() {
  isModal.value = false;
  emits('close');
}

/**
 * 确定方法
 */
const confirmLoading = ref(false);
function setLoading(loading: boolean) {
  confirmLoading.value = loading;
}
function handleConfirm() {
  confirmLoading.value = true;
  emits('confirm');
}

/**
 * 暴露/注册方法
 */
const modalMethods: ModalMethods = {
  setProps,
  openModal,
  closeModal,
  setLoading,
};

onMounted(() => {
  emits('register', modalMethods);
});

defineExpose(modalMethods);
</script>

<template>
  <NModal
    v-bind="getBindValue"
    v-model:show="isModal"
    @close="closeModal"
  >
    <template #header>
      <div class="w-full cursor-move">
        {{ getBindValue.title }}
      </div>
    </template>

    <template #default>
      <slot name="default" />
    </template>

    <template v-if="!$slots.action" #action>
      <NSpace>
        <NButton @click="closeModal">
          取消
        </NButton>
        <NButton type="primary" :loading="confirmLoading" @click="handleConfirm">
          {{
            props.confirmButtonText
          }}
        </NButton>
      </NSpace>
    </template>
    <template v-else #action>
      <slot name="action" />
    </template>
  </NModal>
</template>

<style lang="less">
.cursor-move {
  cursor: move;
}
</style>
